#ifndef ESFERA_H_
#define ESFERA_H_

#include "fisica/objeto.h"
#include <BulletCollision/CollisionShapes/btSphereShape.h>

#include "vertexs.h"
#include "displaylist.h"

#define COMP_X 0.525731112119
#define COMP_Z 0.850650808352

static float data[12][3] = {
   {-COMP_X, 0, COMP_Z},
   {COMP_X, 0, COMP_Z},
   {-COMP_X, 0, -COMP_Z},
   {COMP_X, 0, -COMP_Z},
   {0, COMP_Z, COMP_X},
   {0, COMP_Z, -COMP_X},
   {0, -COMP_Z, COMP_X},
   {0, -COMP_Z, -COMP_X},
   {COMP_Z, COMP_X, 0},
   {-COMP_Z, COMP_X, 0},
   {COMP_Z, -COMP_X, 0},
   {-COMP_Z, -COMP_X, 0}
};

static int indices[20][3] = {
   {1, 4, 0}, {4, 9, 0}, {4, 5, 9}, {8, 5, 4}, {1, 8, 4},
   {1, 10, 8}, {10, 3, 8}, {8, 3, 5}, {3, 2, 5}, {3, 7, 2},
   {3, 10, 7}, {10, 6, 7}, {6, 11, 7}, {6, 0, 11}, {6, 1, 0},
   {10, 1, 6}, {11, 0, 9}, {2, 11, 9}, {5, 2, 9}, {11, 2, 7}
};

class Esfera : public Fisica::Objeto, public DisplayList {
   private:
      Vertexs vertexs;

      void addTring(const Coord &v1, const Coord &v2, const Coord &v3) {
         vertexs.vertex(0, 0, v1, v1);
         vertexs.vertex(0, 0, v2, v2);
         vertexs.vertex(0, 0, v3, v3);
      }

      void subDiv(const Coord &v1, const Coord &v2, const Coord &v3, int nivel) {

         if(nivel == 0) {
            addTring(v1, v2, v3);
            return;
         }

         Coord v12 = ((v1 + v2) * 0.5).normalizar();
         Coord v23 = ((v2 + v3) * 0.5).normalizar();
         Coord v31 = ((v3 + v1) * 0.5).normalizar();

         subDiv(v1, v12, v31, nivel - 1);
         subDiv(v2, v23, v12, nivel - 1);
         subDiv(v3, v31, v23, nivel - 1);
         subDiv(v12, v23, v31, nivel - 1);
      }

   public:
      Esfera(float radio, float masa) : 
         Objeto( *(new btSphereShape(radio)), 21, 21, 10, masa) {
 
            vertexs.grupo(GL_TRIANGLES); 

            for(int i = 0; i < 20; ++i) {
               subDiv(&data[indices[i][0]] [0],
                      &data[indices[i][1]] [0],
                      &data[indices[i][2]] [0], 3);
            }

            vertexs.cerrar();

            inicializar();
         }

      void mover(float dx, float dy, float dz) {
      }

      void dibujar() const {
         glPushMatrix();

         float matrix[16];
         this->transformacion(matrix);
         glMultMatrixf(matrix);

         DisplayList::dibujar();

         glPopMatrix();
      }

      virtual void ejecucion() const {
         glPushAttrib(GL_ALL_ATTRIB_BITS);

         glColor3f(1, 0, 0);

         vertexs.enlazar();
         vertexs.dibujar();

         glPopAttrib();
      }
};

#endif
